/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SLE_CONNECT_HDI
#define SLE_CONNECT_HDI

#include <stdint.h>
#include "sle_hal_errcode.h"
#include "sle_device_config.h"
#include "sle_connect_config.h"

#ifdef _Cplusplus
extern "C" {
#endif

/**
 * @brief Callback invoked when connect state changed.
 * 
 * @param [in] connectId    connection ID.
 * @param [in] addr       address.
 * @param [in] connState connection state { @ref SleAcbState }.
 * @param [in] pairState pairing state { @ref SlePairState }.
 * @param [in] discReason the reason of disconnect { @ref SleDisConnectReason }.
 * @return #void no return value.
 */
typedef void (*SleHdiConnectStateChangedCallback)(uint16_t connectId, const SleDeviceAddress *addr,
    SleAcbState connState, SlePairState pairState, SleDisConnectReason discReason);

/**
 * @brief Callback invoked when connect parameter updated.
 * 
 * @param [in] connectId    connection ID.
 * @param [in] addr       address.
 * @param [in] res     error code.
 * @param [in] param      connection param.
 * @return #void no return value.
 */
typedef void (*SleHdiConnectParamUpdatedCallback)(uint16_t connectId, SleHdiErrorCode res,
    const SleConnectionParamUpdateEvt *param);

/**
 * @brief Callback invoked before the request for updating the connect parameter is complete.
 * 
 * @param [in] connectId    connection ID.
 * @param [in] res     error code.
 * @param [in] param      connection param.
 * @return #void no return value.
 * @par Dependency:
 * @li  SleCommonDefine.h
 * @see SleHdiConnectionCallbacks
 */
typedef void (*SleHdiRequestConnectParamUpdateCallback)(uint16_t connectId, SleHdiErrorCode res,
    const SleConnectParam *param);

/**
 * @if Eng
 * @brief Callback invoked when authentication complete.
 * 
 * @param [in] connectId connection ID.
 * @param [in] addr    address.
 * @param [in] res  error code.
 * @param [in] evt     authentication event.
 * @return #void no return value.
 */
typedef void (*SleHdiAuthCompletedCallback)(uint16_t connectId, const SleDeviceAddress *addr, SleHdiErrorCode res,
    const SleAuthInfo* evt);

/**
 * @brief Callback invoked when pairing complete.
 * 
 * @param [in] connectId connection ID.
 * @param [in] addr    address.
 * @param [in] res  error code.
 * @return #void no return value.
 */
typedef void (*SleHdiPairCompletedCallback)(uint16_t connectId, const SleDeviceAddress *addr, SleHdiErrorCode res);

/**
 * @brief Callback invoked when rssi read complete.
 * 
 * @param [in] connectId connection ID.
 * @param [in] rssi    rssi.
 * @param [in] res  error code.
 * @return #void no return value.
 */
typedef void (*SleHdiReadRssiCallback)(uint16_t connectId, int8_t rssi, SleHdiErrorCode res);

/**
 * @brief Callback invoked when phy set complete.
 *
 * @param [in] connectId connection ID.
 * @param [in] res  error code.
 * @param [in] current phy param
 * @return #void no return value.
 */
typedef void (*SleHdiSetPhyParamCallback)(uint16_t connectId, SleHdiErrorCode res, const SleConnectionPhyParam *param);

typedef struct {
    SleHdiConnectStateChangedCallback OnConnectStateChangedCb;         /*!< @if Eng Connect state changed callback.
                                                                            @else   连接状态改变回调函数。 @endif */
    SleHdiRequestConnectParamUpdateCallback OnConnectParamUpdateReqCb;   /*!< @if Eng Connect param updated callback.
                                                                            @else   连接参数更新回调函数。 @endif */
    SleHdiConnectParamUpdatedCallback OnConnectParamUpdateCb;           /*!< @if Eng Connect param updated callback.
                                                                            @else   连接参数更新回调函数。 @endif */
    SleHdiAuthCompletedCallback OnAuthCompleteCb;                         /*!< @if Eng Authentication complete callback.
                                                                            @else   认证完成回调函数。 @endif */
    SleHdiPairCompletedCallback OnPairCompleteCb;                         /*!< @if Eng Pairing complete callback.
                                                                            @else   配对完成回调函数。 @endif */
    SleHdiReadRssiCallback OnReadRssiCb;                                 /*!< @if Eng Read rssi callback.
                                                                            @else   读取rssi回调函数。 @endif */
    SleHdiSetPhyParamCallback OnSetPhyParamCb;                                 /*!< @if Eng set phy callback.
                                                                            @else   设置phy回调函数。 @endif */
} SleConnectHdiCallbacks;


/**
 * @brief  Send connect request to remote device.
 * 
 * @param [in] addr address
 * @return error code, connection state change result will be returned at { @ref SleHdConnectStateChangedCallback }.
 */
typedef SleHdiErrorCode (*SleHdiConnectRemote)(const SleDeviceAddress *addr);

/**
 * @brief  Send disconnect request to remote device.
 * 
 * @par Description: Send disconnect request to remote device.
 * @param [in] addr address.
 * @return error code, connection state change result will be returned at { @ref SleHdConnectStateChangedCallback }.
 */
typedef SleHdiErrorCode (*SleHdiDisconnectRemote)(const SleDeviceAddress *addr);

/**
 * @brief  Send connection parameter update request to remote device.
 * 
 * @param [in] params connection parameter.
 * @return error code.
 */
typedef SleHdiErrorCode (*SleHdiUpdateConnectParam)(const SleConnectionParamUpdate *params);

/**
 * @brief  Send pairing request to remote device.
 * 
 * @param [in] addr address.
 * @return error code.
 */
typedef SleHdiErrorCode (*SleHdiPairRemote)(const SleDeviceAddress *addr);

/**
 * @brief  Remove pairing.
 * 
 * @param [in] addr address.
 * @return error code.
 */
typedef SleHdiErrorCode (*SleHdiRemovePairedDevice)(const SleDeviceAddress *addr);

/**
 * @brief  Remove all pairing.
 * 
 * @param NULL
 * @return error code.
 */
typedef SleHdiErrorCode (*SleHdiRemoveAllPairs)(void);

/**
 * @brief  Get paired device number.
 * 
 * @param [out] number device number.
 * @return error code.
 */
typedef SleHdiErrorCode (*SleHdiGetPairedDevicesNum)(uint16_t *number);

/**
 * @brief  Get paired device.
 * 
 * @param [out]   addr   linked list of device address.
 * @param [inout] number device number.
 * @return error code.
 */
typedef SleHdiErrorCode (*SleHdiGetPairedDevices)(SleDeviceAddress *addr, uint16_t *number);

/**
 * @brief  Get pair state.
 * 
 * @param [in]  addr  device address.
 * @param [out] state pair state { @ref SlePairState }.
 * @return error code.
 */
typedef SleHdiErrorCode (*SleHdiGetPairState)(const SleDeviceAddress *addr, SlePairState *state);

/**
 * @brief  Read remote device rssi value.
 * 
 * @param [in]  connectId connection ID.
 * @return error code.
 */
typedef SleHdiErrorCode (*SleHdiReadRemoteDeviceRssi)(uint16_t connectId);

typedef SleHdiErrorCode (*SleHdiSetDataLen)(uint16_t connectId, uint16_t payloadLen);

/**
 * brief   Set sle phy param
 *
 * @param   [in] connectId                 - Indicates the ID of the SLE connect.
 * @param   [in] phy_param                 - Indicates Struct of sle phy parameter.
 * @param   [in] mcs                       - Indicates mcs Modulation and Coding Scheme.
 * @return  SleHalErrorCode
 */
typedef SleHdiErrorCode (*SleHdiSetPhyParam)(uint16_t connectId, const SleConnectionPhyParam *phyParam);

/**
 * brief   Set sle mcs value
 *
 * @param   [in] connectId                 - Indicates the ID of the SLE connect.
 * @param   [in] phy_param                 - Indicates Struct of sle phy parameter.
 * @param   [in] mcs                       - Indicates mcs Modulation and Coding Scheme.
 * @return  SleHalErrorCode
 */
typedef SleHdiErrorCode (*SleHdiSetMcsValue)(uint16_t connectId, uint8_t mcs);

/**
 * brief   Set default connect param
 *
 * @param   [in] defaultConnParam                 - default conn param.
 * @return  SleHalErrorCode
 */
typedef SleHdiErrorCode (*SleHdiSetDefaultConnParam)(const SleDefaultConnectionParam *defaultConnParam);

/**
 * @brief  Register SLE connection manager callbacks.
 * 
 * @param [in] callback Callback function.
 * @return error code.
 */
typedef SleHdiErrorCode (*SleHdiRegisterConnectCallbacks)(SleConnectHdiCallbacks *callback);

typedef struct {
    SleHdiConnectRemote connectRemote;                                  /*!< @if Send connect request to remote device.
                                                                            @else   发送连接请求。 @endif */

    SleHdiDisconnectRemote disconnectRemote;                            /*!< @if Send disconnect request to remote device.
                                                                            @else   发送断开连接请求。 @endif */

    SleHdiUpdateConnectParam updateConnectParam;                          /*!< @if Send connection parameter update request to remote device.
                                                                            @else   发送更新连接参数请求。 @endif */

    SleHdiPairRemote sendPairReq;                                       /*!< @if Send pairing request to remote device.
                                                                            @else   发送配对请求。 @endif */

    SleHdiRemovePairedDevice removePairDevice;                          /*!< @if Get paired device.
                                                                            @else   删除配对设备。 @endif */

    SleHdiRemoveAllPairs removeAllPairs;                                /*!< @if Remove pairing.
                                                                            @else   删除所有配对。 @endif */

    SleHdiGetPairedDevicesNum getPairedDevicesNum;                      /*!< @if Get paired device number.
                                                                            @else   获取配对设备数量。 @endif */

    SleHdiGetPairedDevices getPairedDevices;                            /*!< @if Get paired device.
                                                                            @else   获取配对设备。 @endif */

    SleHdiGetPairState getPairState;                                    /*!< @if Get pair state.
                                                                            @else   获取配对状态。 @endif */

    SleHdiReadRemoteDeviceRssi readRemoteRssi;                          /*!< @if Read remote device rssi value.
                                                                            @else   读取对端设备rssi值。 @endif */
    
    SleHdiSetDataLen setDataLen;                                        /*!< @if Set data length.
                                                                            @else   设置数据长度。 @endif */

    SleHdiSetPhyParam setPhyParam;                                        /*!< @if Set phy param.
                                                                            @else   设置phy参数。 @endif */

    SleHdiSetMcsValue setMcsValue;                                        /*!< @if Set mcs value.
                                                                            @else   设置mcs值。 @endif */

    SleHdiSetDefaultConnParam setDefaultConnParam;                        /*!< @if Set default connect param.
                                                                            @else   设置默认连接参数。 @endif */

    SleHdiRegisterConnectCallbacks registerConnectCbks;                 /*!< @if Register SLE connection manager callbacks.
                                                                            @else   注册SLE连接管理回调函数。 @endif */
} SleConnectHdiOpts;

/**
 * @brief   Get SLE connection manager options.
 * 
 * @param   [out] connectOpts
 * @return  SLE connection manager options.
 */
SleHdiErrorCode GetSleConnectHdiOpts(SleConnectHdiOpts *connectOpts);

#ifdef _Cplusplus
}
#endif
#endif /* SLE_CONNECT_HDI */
